﻿#region [ Code Modification History ]
//*******************************************************************************************************
//  FileStreamExtension.cs 
//
//  Code Modification History:
//  -----------------------------------------------------------------------------------------------------
//  15/01/2017 - V. Dennis Kholin
//       Generated original version of source code. 
//*******************************************************************************************************
#endregion 

#region [ Using ]
using System;
using System.IO;
using System.Security.AccessControl;
using Microsoft.Win32.SafeHandles;
#endregion

namespace GZipStreamTool.Base.Extensions
{
    /// <summary>
    /// FileStreamExtension
    /// </summary>
    public class FileStreamExtension : FileStream
    {
        #region [ Members ]
        #endregion

        #region [ Properties ]

        /// <summary>
        /// FileName
        /// </summary>
        public String StreamName
        {
            get { return base.Name; }
        }
        #endregion

        #region [ Inherited Constructors ]

        /// <summary>
        /// FileStreamExtension
        /// </summary>
        /// <param name="path"></param>
        /// <param name="mode"></param>
        public FileStreamExtension(string path, FileMode mode) : base(path, mode)
        {
        }
        /// <summary>
        /// FileStreamExtension
        /// </summary>
        /// <param name="path"></param>
        /// <param name="mode"></param>
        /// <param name="access"></param>
        public FileStreamExtension(string path, FileMode mode, FileAccess access) : base(path, mode, access)
        {
        }
        /// <summary>
        /// FileStreamExtension
        /// </summary>
        /// <param name="path"></param>
        /// <param name="mode"></param>
        /// <param name="access"></param>
        /// <param name="share"></param>
        public FileStreamExtension(string path, FileMode mode, FileAccess access, FileShare share) : base(path, mode, access, share)
        {
        }
        /// <summary>
        /// FileStreamExtension
        /// </summary>
        /// <param name="path"></param>
        /// <param name="mode"></param>
        /// <param name="access"></param>
        /// <param name="share"></param>
        /// <param name="bufferSize"></param>
        public FileStreamExtension(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize) : base(path, mode, access, share, bufferSize)
        {
        }
        /// <summary>
        /// FileStreamExtension
        /// </summary>
        /// <param name="path"></param>
        /// <param name="mode"></param>
        /// <param name="access"></param>
        /// <param name="share"></param>
        /// <param name="bufferSize"></param>
        /// <param name="options"></param>
        public FileStreamExtension(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options) : base(path, mode, access, share, bufferSize, options)
        {
        }
        /// <summary>
        /// FileStreamExtension
        /// </summary>
        /// <param name="path"></param>
        /// <param name="mode"></param>
        /// <param name="access"></param>
        /// <param name="share"></param>
        /// <param name="bufferSize"></param>
        /// <param name="useAsync"></param>
        public FileStreamExtension(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, bool useAsync) : base(path, mode, access, share, bufferSize, useAsync)
        {
        }
        /// <summary>
        /// FileStreamExtension
        /// </summary>
        /// <param name="path"></param>
        /// <param name="mode"></param>
        /// <param name="rights"></param>
        /// <param name="share"></param>
        /// <param name="bufferSize"></param>
        /// <param name="options"></param>
        /// <param name="fileSecurity"></param>
        public FileStreamExtension(string path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize, FileOptions options, FileSecurity fileSecurity) : base(path, mode, rights, share, bufferSize, options, fileSecurity)
        {
        }
        /// <summary>
        /// FileStreamExtension
        /// </summary>
        /// <param name="path"></param>
        /// <param name="mode"></param>
        /// <param name="rights"></param>
        /// <param name="share"></param>
        /// <param name="bufferSize"></param>
        /// <param name="options"></param>
        public FileStreamExtension(string path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize, FileOptions options) : base(path, mode, rights, share, bufferSize, options)
        {
        }
        /// <summary>
        /// FileStreamExtension
        /// </summary>
        /// <param name="handle"></param>
        /// <param name="access"></param>
        public FileStreamExtension(SafeFileHandle handle, FileAccess access) : base(handle, access)
        {
        }
        /// <summary>
        /// FileStreamExtension
        /// </summary>
        /// <param name="handle"></param>
        /// <param name="access"></param>
        /// <param name="bufferSize"></param>
        public FileStreamExtension(SafeFileHandle handle, FileAccess access, int bufferSize) : base(handle, access, bufferSize)
        {
        }
        /// <summary>
        /// FileStreamExtension
        /// </summary>
        /// <param name="handle"></param>
        /// <param name="access"></param>
        /// <param name="bufferSize"></param>
        /// <param name="isAsync"></param>
        public FileStreamExtension(SafeFileHandle handle, FileAccess access, int bufferSize, bool isAsync) : base(handle, access, bufferSize, isAsync)
        {
        }
        #endregion

        #region [ Methods ]
        /// <summary>
        /// Write
        /// </summary>
        /// <returns></returns>
        public FileInfo Write(string file)
        {
            return Write(0, base.Length,file);
        }
        /// <summary>
        /// Write
        /// </summary>
        /// <returns></returns>
        public MemoryStream Write()
        {
            return Write(0, base.Length);
        }

        /// <summary>
        /// Write into memory stream
        /// </summary>
        /// <param name="rangeByteBgn"></param>
        /// <param name="rangeByteEnd"></param>
        /// <returns></returns>
        public MemoryStream Write(long rangeByteBgn,long rangeByteEnd)
        {
            MemoryStream output;
            using (output = new MemoryStream())
            {
                long interval = rangeByteEnd - rangeByteBgn;
                byte[] b = new byte[interval];
                base.Position = rangeByteBgn;
                base.Read(b, 0, (int)interval);
                output.Write(b, 0, b.Length);
            }
                
            return output;
        }
        /// <summary>
        /// Write
        /// </summary>
        /// <param name="rangeByteBgn"></param>
        /// <param name="rangeByteEnd"></param>
        /// <param name="file"></param>
        /// <returns></returns>
        public FileInfo Write(long rangeByteBgn, long rangeByteEnd, string file)
        { 
          
            using (FileStream fs = new FileStream(file, FileMode.Create, FileAccess.Write))
            {

                
                    byte[] buffer = new byte[64*1204]; ; 
                    while (rangeByteEnd > rangeByteBgn)
                    {
                         
                        if (rangeByteBgn + buffer.Length > rangeByteEnd)
                        {
                            buffer = new byte[rangeByteEnd - rangeByteBgn];
                        }
                        
                        base.Position = rangeByteBgn;
                        base.Read(buffer, 0, buffer.Length);
                        rangeByteBgn = base.Position;
                        fs.Write(buffer, 0, buffer.Length);
                        
                    }
               
                 fs.Close();
            }
            return new FileInfo(file);
        }
        
               



        #endregion
    }
}
